package com.fangsheng.io.unit01;

import org.junit.Test;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class OSFileIO {


    static byte[] data = "123456789".getBytes();
    static String path = "D:\\data\\test\\out.txt";

    //基本的文件写入
    @Test
    public void testBasicFile() throws IOException, InterruptedException {
        File file = new File(path);
        FileOutputStream out = new FileOutputStream(file);
        int i = 0;
        while (true) {
            Thread.sleep(1000);
            out.write(data);
            System.out.println("输入正在输入......" + i++);
        }

    }

    @Test
    public void testBufferedFileIO() throws IOException, InterruptedException {
        File file = new File(path);
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        while (true) {
            Thread.sleep(10);
            out.write(data);
        }


    }

    @Test
    public void testRandomAccessFileWrite() throws InterruptedException, IOException {
        RandomAccessFile raf = new RandomAccessFile(path, "rw");
        raf.write("hello mashibing\n".getBytes());
        raf.write("hello seanzhou\n".getBytes());
        System.out.println("write------------");
//        System.in.read();
        raf.seek(4);
        raf.write("ooxx".getBytes());
        System.out.println("seek---------");
//        System.in.read();
        FileChannel rafchannel = raf.getChannel();
        //mmap  堆外  和文件映射的   byte  not  objtect
        MappedByteBuffer map = rafchannel.map(FileChannel.MapMode.READ_WRITE, 0, 4096);
        map.put("@@@".getBytes());  //不是系统调用  但是数据会到达 内核的pagecache
        //曾经我们是需要out.write()  这样的系统调用，才能让程序的data 进入内核的pagecache
        //        //曾经必须有用户态内核态切换
        //        //mmap的内存映射，依然是内核的pagecache体系所约束的！！！
        //        //换言之，丢数据
        //        //你可以去github上找一些 其他C程序员写的jni扩展库，使用linux内核的Direct IO
        //        //直接IO是忽略linux的pagecache
        //        //是把pagecache  交给了程序自己开辟一个字节数组当作pagecache，动用代码逻辑维护一致性/dirty。。。一系列复杂问题
        System.out.println("map--put--------");
//        System.in.read();
//        map.force(); //  flush
        raf.seek(0);
        ByteBuffer buffer = ByteBuffer.allocate(8192);
//        ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
        int read = rafchannel.read(buffer);   //buffer.put()
        System.out.println(buffer);
        buffer.flip();
        System.out.println(buffer);
        for (int i = 0; i < buffer.limit(); i++) {
            Thread.sleep(1000);
            System.out.print(((char) buffer.get(i)));
        }


    }


}
